import { Op } from "sequelize";
import { dictDataTab } from "../../dao/db/relation/system/dictTypeAndDictData";
import SysDictDataModel from "../../dao/model/system/SysDictDataModel";
import SysDictTypeModel from "../../dao/model/system/SysDictTypeModel";
import { ISysDictDataModel } from "../../entities/system/SysDictDataEntity";
import SysDictTypeEntity, { ISysDictTypeModel } from "../../entities/system/SysDictTypeEntity";
import { IPageResponse } from "../../types/CommonType";
import { ValidationError } from "../../utils/errors";
import { pick } from "../../utils/tools";

export class SysDictTypeService {
  /**
   * 添加数据
   */
  public static async add(data: SysDictTypeEntity): Promise<true> {
    // 1. 转换类型
    data = SysDictTypeEntity.transform(data);
    // 2. 数据验证
    const errors = await data.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }

    await SysDictTypeModel.create<ISysDictTypeModel>(data, {
      include: [dictDataTab],
    });
    return true;
  }

  /**
   * 分页获取数据
   */
  public static async findByPage(current: number, size: number, where?): Promise<IPageResponse> {
    let data = await SysDictTypeModel.findAndCountAll<ISysDictTypeModel>({
      offset: size * (current - 1),
      limit: size,
      where,
    });

    const result: IPageResponse = {
      total: data.count,
      list: data.rows.map((item) => item.dataValues),
    };
    return result;
  }

  /**
   * 通过id获取数据
   */
  public static async findById(id: string) {
    const typeData = await SysDictTypeModel.findByPk<ISysDictTypeModel>(id, {
      include: [dictDataTab],
    });

    return typeData;
  }

  /**
   * 修改数据
   */
  public static async update(data: SysDictTypeEntity) {
    const result = SysDictTypeModel.update<ISysDictTypeModel>(data, {
      where: {
        id: data.id,
      },
    });

    /**
     * 删除多余的字典数据
     */
    async function deleteUnnecessary() {
      const dictData = await SysDictDataModel.findAll<ISysDictDataModel>({
        where: {
          typeId: data.id,
        },
      });
      const alreadyIds = dictData.map((item) => item.dataValues.id);
      const newIds = data.dictData!.map((item) => item.id);

      const ids = alreadyIds.filter((id) => !newIds.includes(id));

      if (ids.length > 0) {
        SysDictDataModel.destroy({
          where: {
            id: {
              [Op.in]: ids,
            },
          },
        });
      }
    }
    deleteUnnecessary();

    /**
     * 操作字典数据
     */
    async function createDictData() {
      const dictData = data.dictData!.map((item) => ({
        ...item,
        dictType: data.dictType,
        typeId: data.id,
      }));
      await Promise.allSettled(
        dictData.map(async (item) => {
          // 有id走更新，没id走创建
          if (item.id) {
            await SysDictDataModel.update(item, {
              where: {
                id: item.id,
              },
            });
          } else {
            await SysDictDataModel.create(item);
          }
        })
      );
    }
    createDictData();

    return result;
  }

  /**
   * 删除数据
   */
  public static async delete(id: string) {
    return SysDictTypeModel.destroy({
      where: {
        id,
      },
    });
  }

  /**
   * 获取下拉选择数据
   */
  public static async findOptionSelect(dictType: string) {
    const result = await SysDictDataModel.findAll<ISysDictDataModel>({
      where: {
        dictType,
        status: "1",
      },
    });
    return result.map(({ dataValues }) => pick(dataValues, ["dictLabel", "dictValue", "dictType"]));
  }
}
